home *** CD-ROM | disk | FTP | other *** search
- /*
- * $RCSfile: logTransDeallocPages.c,v $
- * $Revision: 1.1.1.1 $
- * $Date: 1996/05/04 21:56:02 $
- */
- /**********************************************************************
- * EXODUS Database Toolkit Software
- * Copyright (c) 1991 Computer Sciences Department, University of
- * Wisconsin -- Madison
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
- * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.
- * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
- * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * The EXODUS Project Group requests users of this software to return
- * any improvements or extensions that they make to:
- *
- * EXODUS Project Group
- * c/o David J. DeWitt and Michael J. Carey
- * Computer Sciences Department
- * University of Wisconsin -- Madison
- * Madison, WI 53706
- *
- * or exodus@cs.wisc.edu
- *
- * In addition, the EXODUS Project Group requests that users grant the
- * Computer Sciences Department rights to redistribute these changes.
- **********************************************************************/
-
- #include "sysdefs.h"
- #include "ess.h"
- #include "checking.h"
- #include "trace.h"
- #include "error.h"
- #include "list.h"
- #include "pool.h"
- #include "tid.h"
- #include "io.h"
- #include "lock.h"
- #include "object.h"
- #include "msgdefs.h"
- #include "thread.h"
- #include "semaphore.h"
- #include "latch.h"
- #include "link.h"
- #include "lsn.h"
- #include "bf.h"
- #include "bf_macro.h"
- #include "volume.h"
- #include "openlog.h"
- #include "trans.h"
- #include "page.h"
- #include "bitmap.h"
- #include "deallocinfo.h"
- #include "io_extfuncs.h"
- #include "trans_extfuncs.h"
- #include "bf_extfuncs.h"
- #include "bm_globals.h"
-
-
- /*
- * This function traverses the list of pages to deallocate (attached
- * to the transRec) and logs the deallocation. It collects chunks
- * of pages to log in one record. These chunks are created by
- * cl_DeallocPages. The chunk size will be the minimum of
- * MAX_PIDLIST_SIZE, pages on one bitmap page, and the chunk size
- * from the call to cl_DeallocPages.
- */
-
- int
- logTransDeallocPages (
-
- TRANSREC *transRec,
- LIST *pendingBitmapList
- )
- {
-
- PID pidList[MAX_PIDLIST_SIZE];
- PAGEDEALLOCINFO *currPage;
- PAGE2SIZE page2size;
- PAGECONTEXT *currBitmapPage;
- PAGECONTEXT *pendingBitmapPage;
- VOLREC *volRec;
- LIST bitmapList;
- int chunk;
- int totalChunks;
- int totalPages;
- int loggedPages;
- int chunkPages;
-
- TRACE(TR_TRANS, TR_LEVEL_1);
-
- SM_ASSERT(LEVEL_3, LIST_EMPTY(pendingBitmapList));
-
- /*
- * See if there is any work to be done;
- */
- currPage = (PAGEDEALLOCINFO*) FIRST_LIST_ELEMENT(&(transRec->pageDeallocList));
- if (currPage == NULL) {
- return(esmNOERROR);
- }
-
- /*
- * Initialize locals
- */
- initializeList(&bitmapList);
-
- /*
- * Process each chunk of pages
- */
- while (currPage != NULL) {
-
- CHECK_PAGEDEALLOCINFO_MAGIC(currPage);
- page2size = currPage->page2size;
- SM_ASSERT(LEVEL_3, LIST_EMPTY(&bitmapList));
-
- /*
- * This is the first page in a chunk, so see how many pages
- * to deallocate. Deallocate in chunks which are of
- * a size <= MAX_PIDLIST_SIZE.
- */
- SM_ASSERT(LEVEL_3, currPage->pageCount > 0);
- totalPages = currPage->pageCount;
- totalChunks = (totalPages / MAX_PIDLIST_SIZE) +
- ((totalPages%MAX_PIDLIST_SIZE) ? 1:0);
- loggedPages = 0;
- for (chunk = 0; chunk < totalChunks; chunk++) {
-
- chunkPages = 0;
- while (chunkPages < MAX_PIDLIST_SIZE) {
-
- /*
- * Make sure the page is the right size and add it
- * to the list
- */
- SM_ASSERT(LEVEL_3, page2size == currPage->page2size);
- pidList[chunkPages] = currPage->pid;
- chunkPages++;
-
- /*
- * Get the next page to log
- */
- currPage = (PAGEDEALLOCINFO*) NEXT_LIST_ELEMENT(&(currPage->list));
- if (currPage == NULL) break;
- if (currPage->pageCount != 0) {
- /*
- * Starting new chunk, so make sure we've logged
- * everything for the current chunk
- */
- SM_ASSERT(LEVEL_3, (chunkPages + MAX_PIDLIST_SIZE * chunk) == totalPages);
- SM_ASSERT(LEVEL_3, chunk+1 == totalChunks);
- break;
- }
- }
-
- /*
- * Log the deallocation, but don't actually perform it
- */
- if (io_DeallocPages(page2size, chunkPages, pidList, &bitmapList, TRUE, FALSE) != esmNOERROR) {
- SM_ERROR(TYPE_CRASH, esmINTERNAL);
- }
-
- /*
- * For each bitmap page, add it to the pending list
- * if not already there.
- */
- while ((currBitmapPage = (PAGECONTEXT*) listDeq(&bitmapList)) != NULL) {
- /*
- * see if its already on the pending list
- */
- pendingBitmapPage = (PAGECONTEXT*) FIRST_LIST_ELEMENT(pendingBitmapList);
- while (pendingBitmapPage != NULL) {
- if (PIDEQ(currBitmapPage->pid, pendingBitmapPage->pid)) {
- /* the page is on the list, so break */
- break;
- }
- pendingBitmapPage = (PAGECONTEXT*) NEXT_LIST_ELEMENT(&(pendingBitmapPage->list));
- }
-
- if (pendingBitmapPage == NULL) {
- /*
- * It's not on the pending list, so add it,
- * release its semaphore, and mark it pending
- */
- listEnq(pendingBitmapList, &(currBitmapPage->list));
- signalSemaphore( &(currBitmapPage->groupLink->pageHash->semaphore) );
- currBitmapPage->groupLink->pageHash->pendingOpCount++;
- currBitmapPage->bitsChanged = 0;
-
- /*
- * Mark its volume header as having pending
- * operations
- */
- volRec = io_FindVolRec(currBitmapPage->pid.volid);
- if (volRec == NULL) {
- SM_ERROR(TYPE_FATAL, esmINTERNAL);
- }
- volRec->headerLink->pageHash->pendingOpCount++;
-
- } else {
-
- /*
- * It's on the pending list, release its
- * semaphore, unfix it, and return it to the pool.
- */
- signalSemaphore( &(currBitmapPage->groupLink->pageHash->semaphore) );
- bf_UnfixPage(currBitmapPage->groupLink, BF_DEFAULT, TRUE);
- poolEnq(&PageContextPool, &(currBitmapPage->list));
-
- }
- }
-
- loggedPages += chunkPages;
-
- }
-
- SM_ASSERT(LEVEL_3, loggedPages == totalPages);
-
- }
-
- return(esmNOERROR);
- }
-